<template>
  <div class="container">
    <h3>根据坐标，回显点、线、多边形、圆</h3>
    <h4>
      <el-button type="primary" size="mini" @click="showPoint">显示点</el-button>
      <el-button type="primary" size="mini" @click="showLine">显示线</el-button>
      <el-button type="primary" size="mini" @click="showCircle">显示圆</el-button>
      <el-button type="primary" size="mini" @click="showPolygon">显示多边形</el-button>
      <el-button type="primary" size="mini" @click="clearLayer">清除图层</el-button>
    </h4>
    <div id="vue-openlayers"></div>
  </div>
</template>

<script>
import 'ol/ol.css';
import {Map,View} from 'ol'
import TileLayer from 'ol/layer/Tile'
import XYZ from "ol/source/XYZ";
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Feature from 'ol/Feature'; // 用来创建要素
import { Point,LineString,Polygon,Circle } from 'ol/geom'; // 用来创建几何图形
import Style from 'ol/style/Style'; // 用来创建样式
import Fill from 'ol/style/Fill'; // 用来创建填充样式
import Stroke from 'ol/style/Stroke'; // 用来创建边线样式
import CircleStyle from 'ol/style/Circle'; // 用来创建圆形样式
export default {
  data() {
    return {
      map: null,
      dataSource: new VectorSource({ wrapX: false }),
      pointData: [116, 39],
      lineData: [
        [116, 39],
        [116.005, 39],
        [114.005, 50.005]
      ],
      polygonData: [[ // 多边形数据源
        [112.95855166015626, 23.169535604187015],
        [112.98601748046876, 23.106364217468265],
        [113.08489443359376, 23.15992256707764],
        [112.95855166015626, 23.169535604187015]
      ]],
      circleData: {
        circleCenter: [115.992, 39],
        circleRadius: 0.005
      },
      myfeature: null
    }
  },

  mounted() {
    this.initMap();
  },
  methods: {
    // 设置vector图层样式
    featureStyle() {
      let style = new Style({
        fill: new Fill({
          color: '#00f'
        }),
        stroke: new Stroke({
          width: 10,
          color: '#0f0'
        }),
        image: new CircleStyle({
          radius: 10,
          fill: new Fill({
            color: '#ff0000'
          })
        })
      })
      return style;
    },

    // 清除vector数据源
    clearLayer() {
      this.dataSource.clear();
    },
    // 根据feature适配到相应的地图位置
    fitView() {
      let size = this.map.getSize();
      this.map.getView().fit(this.myfeature, {
        size: size,
        padding: [50, 50, 50, 50],
        maxZoom: 17
      })
    },
    // 显示点
    showPoint() {
      let pointFeature = new Feature({
        geometry: new Point(this.pointData) // 设置几何图形 geometry代表几何图形
      })
      this.dataSource.addFeature(pointFeature); // 将要素添加到数据源
      this.myfeature = pointFeature.getGeometry()
      this.fitView()
    },

    // 显示线段
    showLine() {
      let lineFeature = new Feature({
        geometry: new LineString(this.lineData)
      })
      this.dataSource.addFeature(lineFeature);
      this.myfeature = lineFeature.getGeometry()
      this.fitView()
    },

    // 显示圆
    showCircle() {
      let circleFeature = new Feature({
        geometry: new Circle(this.circleData.circleCenter, this.circleData.circleRadius)
      })
      this.dataSource.addFeature(circleFeature);
      this.myfeature = circleFeature.getGeometry()
      this.fitView()
    },

    // 显示多边形
    showPolygon() {
      let polygonFeature = new Feature({
        geometry: new Polygon(this.polygonData)
      })
      this.dataSource.addFeature(polygonFeature);
      this.myfeature = polygonFeature.getGeometry()
      this.fitView()
    },

    initMap() {
      let raster = new TileLayer({
        source: new XYZ({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7'
        })
      })

      let feature_Layer = new VectorLayer({
        source: this.dataSource, // 设置数据源
        style: this.featureStyle() // 设置样式
      })

      this.map = new Map({
        target: 'vue-openlayers',
        layers: [raster, feature_Layer],
        view: new View({
          projection: 'EPSG:4326',
          center: [116, 39],
          zoom: 4
        })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
    width: 840px;
    height: 550px;
    margin: 50px auto;
    border: 1px solid #ccc;
    #vue-openlayers {
      width: 800px;
      height: 420px;
      margin: 0 auto;
      border: 1px solid #42b983;
      position: relative;
    }
  }
</style>
